﻿using Stiline.DAL.DbContext;
using Stiline.Interfaces;
using System;
using System.Data.Linq;
using System.Linq;
using System.Linq.Expressions;

namespace Stiline.DAL.Repositories
{
    public abstract class BaseRepository<T, DbT>: IRepository<T> where T : class, IEntity where DbT: class, IEntity, new()
    {
        protected readonly DbContextDataContext Context = new DbContextDataContext();

        public T Get(int id)
        {
            return GetTable().Select(GetConverter()).SingleOrDefault(x => x.Id.Equals(id));
        }

        public IQueryable<T> GetAll()
        {
            return GetTable().Select(GetConverter());
        }

        public bool Save(T entity)
        {
            DbT dbEntity;

            if (entity.Id.Equals(0))
            {
                dbEntity = new DbT();
            }
            else
            {
                dbEntity = GetTable().SingleOrDefault(x => x.Id.Equals(entity.Id));
                if (dbEntity == null)
                {
                    return false;
                }
            }

            UpdateEntry(dbEntity, entity);

            if (entity.Id.Equals(0))
            {
                GetTable().InsertOnSubmit(dbEntity);
            }

            Context.SubmitChanges();

            entity.Id = dbEntity.Id;
            return true;
        }

        public bool Delete(int id)
        {
            var dbEntity = GetTable().SingleOrDefault(x => x.Id.Equals(id));

            if (dbEntity == null)
            {
                return false;
            }

            GetTable().DeleteOnSubmit(dbEntity);

            Context.SubmitChanges();
            return true;
        }

        public bool Delete(T entity)
        {
            return Delete(entity.Id);
        }

        protected abstract Table<DbT> GetTable();

        protected abstract Expression<Func<DbT, T>> GetConverter();

        protected abstract void UpdateEntry(DbT dbEntity, T entity);
    }
}
